/**
 * Notes: 用户模块业务逻辑 - 宠物门店预约小程序
 * Date: 2025-01-27 
 */

const BaseService = require('./base_service.js');
const cloudBase = require('../../framework/cloud/cloud_base.js');
const UserModel = require('../model/user_model.js');
const timeUtil = require('../../framework/utils/time_util.js');

class PassportService extends BaseService {

	/**
	 * 用户登录/注册（新方法：直接使用 openid）
	 * @param {string} openid 用户 openid（由云函数框架自动获取）
	 * @param {Object} userInfo 用户信息
	 * @returns {Object} 登录结果
	 */
	async loginWithOpenid(openid, userInfo = {}) {
		if (!openid) {
			throw new Error('openid 不能为空');
		}

		console.log('登录使用的 openid:', openid);

		// 检查用户是否存在
		let where = {
			_id: openid
		};
		let user = await UserModel.getOne(where);

		if (!user) {
			// 新用户注册
			console.log('新用户注册，openid:', openid);
			user = await this.registerUser(openid, userInfo);
		} else {
			// 更新登录信息
			console.log('老用户登录，openid:', openid);
			await this.updateLoginInfo(openid, userInfo);
		}

		// 生成token (这里简化处理，实际项目中应该使用JWT)
		let token = this.generateToken(openid);

		return {
			token: token,
			userInfo: {
				_id: user._id,
				nickName: user.nickName,
				avatarUrl: user.avatarUrl,
				balance: user.balance,
				phone: user.phone
			},
			adminInfo: user.adminId ? { adminId: user.adminId } : null
		};
	}

	/**
	 * 用户登录/注册（保留原方法以兼容）
	 * @param {string} code 微信登录code
	 * @param {Object} userInfo 用户信息
	 * @returns {Object} 登录结果
	 */
	async login(code, userInfo = {}) {
		// 通过code获取openid
		let openid = await this.getOpenIdByCode(code);
		if (!openid) {
			throw new Error('获取openid失败');
		}

		// 调用新方法
		return await this.loginWithOpenid(openid, userInfo);
	}

	/**
	 * 通过code获取openid
	 * @param {string} code 微信登录code
	 * @returns {string} openid
	 */
	async getOpenIdByCode(code) {
		try {
			// 调用微信API获取openid
			const cloud = cloudBase.getCloud();
			const result = await cloud.openapi.sns.jscode2session({
				appid: cloud.APPID,
				secret: cloud.APPSECRET,
				js_code: code,
				grant_type: 'authorization_code'
			});

			if (result && result.openid) {
				console.log('获取到真实openid:', result.openid);
				return result.openid;
			} else {
				console.error('微信API返回错误:', result);
				throw new Error('获取openid失败: ' + (result.errmsg || '未知错误'));
			}
		} catch (error) {
			console.error('调用微信API失败:', error);
			// 开发环境降级方案：使用一个稳定的哈希值来生成唯一的openid
			// 确保同一微信用户的 code 每次生成的 openid 都相同
			const crypto = require('crypto');
			const mockOpenid = 'o' + crypto.createHash('md5').update(code).digest('hex').substring(0, 27);
			console.log('使用模拟openid:', mockOpenid);
			return mockOpenid;
		}
	}

	/**
	 * 注册新用户
	 * @param {string} openid 用户openid
	 * @param {Object} userInfo 用户信息
	 * @returns {Object} 用户信息
	 */
	async registerUser(openid, userInfo) {
		let data = {
			_id: openid,
			nickName: userInfo.nickName || '',
			avatarUrl: userInfo.avatarUrl || '',
			phone: null, // 修复：使用 null 而不是空字符串，避免唯一索引冲突
			balance: 0,
			adminId: '',
			createTime: timeUtil.time(),
			updateTime: timeUtil.time()
		};

		try {
			await UserModel.insert(data);
			return data;
		} catch (error) {
			// 处理avatarUrl重复键错误
			if (error.message && error.message.includes('duplicate key error') && error.message.includes('avatarUrl')) {
				console.log('avatarUrl重复，尝试使用唯一化处理');
				// 在avatarUrl后添加时间戳使其唯一
				if (data.avatarUrl) {
					data.avatarUrl = data.avatarUrl + '?t=' + Date.now();
				}
				await UserModel.insert(data);
				return data;
			} else {
				// 其他错误直接抛出
				throw error;
			}
		}
	}

	/**
	 * 更新登录信息
	 * @param {string} openid 用户openid
	 * @param {Object} userInfo 用户信息
	 */
	async updateLoginInfo(openid, userInfo) {
		let where = {
			_id: openid
		};

		let updateData = {
			updateTime: timeUtil.time()
		};

		// 更新用户信息（如果提供了新信息）
		if (userInfo.nickName) updateData.nickName = userInfo.nickName;
		if (userInfo.avatarUrl) updateData.avatarUrl = userInfo.avatarUrl;

		await UserModel.edit(where, updateData);
	}

	/**
	 * 获取手机号码
	 * @param {string} cloudID 云函数ID
	 * @returns {string} 手机号
	 */
	async getPhone(cloudID) {
		let cloud = cloudBase.getCloud();
		let res = await cloud.getOpenData({
			list: [cloudID],
		});
		if (res && res.list && res.list[0] && res.list[0].data) {
			return res.list[0].data.phoneNumber;
		}
		return '';
	}

	/**
	 * 获取用户详情
	 * @param {string} userId 用户ID
	 * @returns {Object} 用户详情
	 */
	async getMyDetail(userId) {
		let where = {
			_id: userId
		};
		let fields = '_id,nickName,avatarUrl,phone,balance,adminId,createTime';
		return await UserModel.getOne(where, fields);
	}

	/**
	 * 更新用户基础信息
	 * @param {string} userId 用户ID
	 * @param {Object} userData 用户数据
	 */
	async editBase(userId, userData) {
		let {
			nickName,
			avatarUrl,
			phone
		} = userData;

		let where = {
			_id: userId
		};

		// 检查用户是否存在
		let user = await UserModel.getOne(where);
		if (!user) {
			throw new Error('用户不存在');
		}

		let updateData = {
			updateTime: timeUtil.time()
		};

		if (nickName !== undefined) updateData.nickName = nickName;
		if (avatarUrl !== undefined) updateData.avatarUrl = avatarUrl;
		if (phone !== undefined) updateData.phone = phone;

		await UserModel.edit(where, updateData);
	}

	/**
	 * 更新用户余额
	 * @param {string} userId 用户ID
	 * @param {number} amount 金额变化（分）
	 * @returns {Object} 更新结果
	 */
	async updateBalance(userId, amount) {
		let where = {
			_id: userId
		};

		// 检查用户是否存在
		let user = await UserModel.getOne(where);
		if (!user) {
			throw new Error('用户不存在');
		}

		let newBalance = user.balance + amount;
		if (newBalance < 0) {
			throw new Error('余额不足');
		}

		let updateData = {
			balance: newBalance,
			updateTime: timeUtil.time()
		};

		await UserModel.edit(where, updateData);
		return { balance: newBalance };
	}

	/**
	 * 生成token
	 * @param {string} openid 用户openid
	 * @returns {string} token
	 */
	generateToken(openid) {
		// 这里应该使用JWT生成token
		// 为了演示，直接返回简单的token
		return 'token_' + openid + '_' + Date.now();
	}


}

module.exports = PassportService;